home *** CD-ROM | disk | FTP | other *** search
/ Dr. Windows 3 / dr win3.zip / dr win3 / PROGRAMR / OLE2BOOK.ZIP / CHAP08.ZIP / CHAP08 / PATRON / PAGEMOUS.CPP < prev    next >
C/C++ Source or Header  |  1993-06-07  |  16KB  |  661 lines

  1. /*
  2.  * PAGEMOUS.CPP
  3.  * Modifications for Chapter 8
  4.  *
  5.  * Implementation of mouse-related member functions of CPage.
  6.  * The remainder is in PAGE.CPP.  This separate file keeps this
  7.  * grungy hit-testing/drawing code out of our way.
  8.  *
  9.  * Copyright (c)1993 Microsoft Corporation, All Rights Reserved
  10.  *
  11.  * Kraig Brockschmidt, Software Design Engineer
  12.  * Microsoft Systems Developer Relations
  13.  *
  14.  * Internet  :  kraigb@microsoft.com
  15.  * Compuserve:  >INTERNET:kraigb@microsoft.com
  16.  */
  17.  
  18.  
  19. #include "patron.h"
  20.  
  21.  
  22. //Lookups into the array using g_rgHTCode[x+y*3] in PAGEMOUS.CPP
  23. #define YTOP            0
  24. #define YMID            1
  25. #define YBOT            2
  26. #define XLEFT           0
  27. #define XMID            1
  28. #define XRIGHT          2
  29.  
  30. //Values to restrict sizing in CPage::OnMouseMove
  31. #define SIZINGTOP       0x0001
  32. #define SIZINGBOTTOM    0x0002
  33. #define SIZINGLEFT      0x0004
  34. #define SIZINGRIGHT     0x0008
  35.  
  36.  
  37. //This array is for hit-testing lookups
  38. static UINT g_rgHTCode[9]={HTTOPLEFT, HTTOP, HTTOPRIGHT
  39.     , HTLEFT, HTCLIENT, HTRIGHT, HTBOTTOMLEFT, HTBOTTOM, HTBOTTOMRIGHT};
  40.  
  41.  
  42. //This is for restricting tracking based on the hit-test
  43. static UINT g_rguSizingFlags[9]={SIZINGTOP | SIZINGLEFT, SIZINGTOP
  44.     , SIZINGTOP | SIZINGRIGHT, SIZINGLEFT, 0, SIZINGRIGHT
  45.     , SIZINGBOTTOM | SIZINGLEFT, SIZINGBOTTOM, SIZINGBOTTOM | SIZINGRIGHT};
  46.  
  47.  
  48.  
  49. /*
  50.  * CPage::OnLeftDown
  51.  *
  52.  * Purpose:
  53.  *  Called when the user clicks with the left button on this page.
  54.  *  We find the object under that position that is visibly on top
  55.  *  (always the first one under this location in the page list since
  56.  *  we paint in reverse order) and select it.
  57.  *
  58.  * Parameters:
  59.  *  uKeys           UINT carrying the key state.
  60.  *  x, y            UINT coordinates of the click in device units.
  61.  *
  62.  * Return Value:
  63.  *  BOOL            Indicates if the action changed the object.
  64.  */
  65.  
  66. BOOL CPage::OnLeftDown(UINT uKeys, UINT x, UINT y)
  67.     {
  68.     UINT        iTenant;
  69.     LPTENANT    pTenant;
  70.     RECT        rc;
  71.  
  72.     //CHAPTER8MOD
  73.     if (HTCAPTION==m_uHTCode)
  74.         return DragDrop(uKeys, x, y);
  75.     //End CHAPTER8MOD
  76.  
  77.  
  78.     /*
  79.      * See if we have to start sizing (which always happens on current
  80.      * tenant).  m_uHTCode is set in OnNCHitTest below.
  81.      */
  82.     if (HTNOWHERE!=m_uHTCode && HTCLIENT!=m_uHTCode)
  83.         {
  84.         //We are sizing, so start tracking
  85.         m_pTenantCur->RectGet(&m_rcl, TRUE);
  86.         SetCapture(m_hWnd);
  87.         m_fTracking=TRUE;
  88.  
  89.         m_hDC=GetDC(m_hWnd);
  90.  
  91.         //Place the rectangle exactly where it is on the screen.
  92.         RECTFROMRECTL(rc, m_rcl)
  93.         OffsetRect(&rc, -(int)m_pPG->m_xPos, -(int)m_pPG->m_yPos);
  94.         RECTLFROMRECT(m_rcl, rc);
  95.         m_rclOrg=m_rcl;
  96.  
  97.         DrawFocusRect(m_hDC, &rc);
  98.  
  99.         m_pPG->CalcBoundingRect(&rc, TRUE);
  100.         RECTLFROMRECT(m_rclBounds, rc);
  101.         return FALSE;
  102.         }
  103.  
  104.     iTenant=TenantFromPoint(x, y, &pTenant);
  105.  
  106.     if (NULL==pTenant)
  107.         return FALSE;
  108.  
  109.     //If this one is already current, we might be now sizing.
  110.     if (pTenant==m_pTenantCur)
  111.         return FALSE;
  112.  
  113.     //Deselect the current tenant
  114.     if (NULL!=m_pTenantCur)
  115.         m_pTenantCur->Select(FALSE);
  116.  
  117.     //Move this tenant to the top of the list
  118.     m_iTenantCur=0;
  119.  
  120.     SendMessage(m_hWndTenantList, LB_DELETESTRING, iTenant, 0L);
  121.     SendMessage(m_hWndTenantList, LB_INSERTSTRING, 0, (LONG)pTenant);
  122.  
  123.     //Select and repaint the new tenant to show it up front
  124.     m_pTenantCur=pTenant;
  125.  
  126.     m_pTenantCur->Repaint();
  127.     m_pTenantCur->Select(TRUE);
  128.  
  129.     return FALSE;
  130.     }
  131.  
  132.  
  133.  
  134.  
  135.  
  136.  
  137. /*
  138.  * CPage::OnLeftUp
  139.  *
  140.  * Purpose:
  141.  *  Called when the user clicks up with the left button on this page.
  142.  *  We stop tracking on this message, if necessary, and resize the object.
  143.  *
  144.  * Parameters:
  145.  *  uKeys           UINT carrying the key state.
  146.  *  x, y            UINT coordinates of the click in device units.
  147.  *
  148.  * Return Value:
  149.  *  BOOL            Indicates if this action changed the object.
  150.  */
  151.  
  152. BOOL CPage::OnLeftUp(UINT uKeys, UINT x, UINT y)
  153.     {
  154.     RECT    rc, rcT;
  155.  
  156.     if (!m_fTracking)
  157.         return FALSE;
  158.  
  159.     //Remove the dotted rectangle.
  160.     RECTFROMRECTL(rc, m_rcl)
  161.     DrawFocusRect(m_hDC, &rc);
  162.     ReleaseDC(m_hWnd, m_hDC);
  163.  
  164.     ReleaseCapture();
  165.     m_fTracking=FALSE;
  166.  
  167.     //If the original and new rects are the same, nothing happened.
  168.     RECTFROMRECTL(rcT, m_rclOrg);
  169.  
  170.     if (EqualRect(&rc, &rcT))
  171.         return FALSE;
  172.  
  173.     RECTFROMRECTL(rcT, m_rclOrg);
  174.     InvalidateRect(m_hWnd, &rcT, TRUE);
  175.  
  176.     //Invalidate on the screen before accounting for scrolling
  177.     InvalidateRect(m_hWnd, &rc, TRUE);
  178.  
  179.     //Factor in the scrolling and tell the tenant where it now stands.
  180.     OffsetRect(&rc, (int)m_pPG->m_xPos, (int)m_pPG->m_yPos);
  181.     RECTLFROMRECT(m_rcl, rc);
  182.     m_pTenantCur->RectSet(&m_rcl, TRUE);
  183.  
  184.     UpdateWindow(m_hWnd);
  185.     return TRUE;
  186.     }
  187.  
  188.  
  189.  
  190.  
  191.  
  192. /*
  193.  * CPage::OnLeftDoubleClick
  194.  *
  195.  * Purpose:
  196.  *  Called when the user double-clicks with the left button on this page.
  197.  *  We find the object under that position that is visibly on top
  198.  *  (always the first one under this location in the page list since
  199.  *  we paint in reverse order) and activate it.
  200.  *
  201.  * Parameters:
  202.  *  uKeys           UINT carrying the key state.
  203.  *  x, y            UINT coordinates of the click in device units.
  204.  *
  205.  * Return Value:
  206.  *  BOOL            Indicates if the action changed the object.
  207.  */
  208.  
  209. BOOL CPage::OnLeftDoubleClick(UINT uKeys, UINT x, UINT y)
  210.     {
  211.     /*
  212.      * The current tenant is the only one that can be activated, so
  213.      * we just have to make sure the mouse is there.  For that we can
  214.      * use the last hit-test code we saw since it's updated on every
  215.      * mouse move.
  216.      */
  217.  
  218.     if (HTNOWHERE!=m_uHTCode)
  219.         return m_pTenantCur->Activate(OLEIVERB_PRIMARY);
  220.  
  221.     return FALSE;
  222.     }
  223.  
  224.  
  225.  
  226.  
  227.  
  228.  
  229. /*
  230.  * CPage::OnNCHitTest
  231.  *
  232.  * Purpose:
  233.  *  Processes WM_NCHITTEST on a page so we can check for hits on the
  234.  *  handles of the selected object for resizing.  We only save information
  235.  *  for ourselves and do not interfere with normal hit-testing.
  236.  *
  237.  * Parameters:
  238.  *  x, y            UINT device coordinates to check.
  239.  *
  240.  * Return Value:
  241.  *  None
  242.  */
  243.  
  244. void CPage::OnNCHitTest(UINT x, UINT y)
  245.     {
  246.     RECT        rc;
  247.     RECTL       rcl;
  248.     int         iMid1, iMid2;
  249.     int         xHit, yHit;
  250.     POINT       pt;
  251.     int         x0, y0;
  252.  
  253.     //By default we won't start sizing on a click and don't hit an object.
  254.     m_uSizingFlags=0;
  255.     m_uHTCode=HTNOWHERE;
  256.  
  257.     if (NULL==m_pTenantCur)
  258.         return;
  259.  
  260.     //Convert device points to our coordinates
  261.     m_pTenantCur->RectGet(&rcl, FALSE);
  262.     RECTFROMRECTL(rc, rcl);
  263.     RectConvertMappings(&rc, NULL, TRUE);
  264.     OffsetRect(&rc, -(int)m_pPG->m_xPos, -(int)m_pPG->m_yPos);
  265.  
  266.     SETPOINT(pt, x, y);
  267.     ScreenToClient(m_hWnd, &pt);
  268.     x0=pt.x;
  269.     y0=pt.y;
  270.  
  271.     if (x0 < rc.left || x0 > rc.right)
  272.         return;
  273.  
  274.     if (y0 < rc.top || y0 > rc.bottom)
  275.         return;
  276.  
  277.     //It's at least in the object.
  278.     m_uHTCode=HTCLIENT;
  279.  
  280.     //Check for hits in horizontal regions
  281.     xHit=-1;
  282.     iMid1=rc.left+((rc.right-rc.left-CXYHANDLE) >> 1);
  283.     iMid2=rc.left+((rc.right-rc.left+CXYHANDLE) >> 1);
  284.  
  285.     if (x0 >= rc.left && x0 <= rc.left+CXYHANDLE)
  286.         xHit=XLEFT;
  287.     else if (x0 >= iMid1 && x0 <= iMid2)
  288.         xHit=XMID;
  289.     else if (x0 >= rc.right-CXYHANDLE && x0 <= rc.right)
  290.         xHit=XRIGHT;
  291.  
  292.     //CHAPTER8MOD
  293.     //Don't exit yet if we didn't hit a handle--might hit a y edge.
  294.     //End CHAPTER8MOD
  295.  
  296.     //Check for hits in vertical regions
  297.     yHit=-1;
  298.     iMid1=rc.top+((rc.bottom-rc.top-CXYHANDLE) >> 1);
  299.     iMid2=rc.top+((rc.bottom-rc.top+CXYHANDLE) >> 1);
  300.  
  301.     if (y0 >= rc.top && y0 <= rc.top+CXYHANDLE)
  302.         yHit=YTOP;
  303.     else if (y0 >= iMid1 && y0 <= iMid2)
  304.         yHit=YMID;
  305.     else if (y0 >= rc.bottom-CXYHANDLE && y0 <= rc.bottom)
  306.         yHit=YBOT;
  307.  
  308.     //CHAPTER8MOD
  309.     /*
  310.      * If we hit any edge, but didn't hit a ha